package com.ruoyi.teaching.service.impl;

import java.util.List;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ruoyi.common.core.exception.ServiceException;
import com.ruoyi.common.core.utils.DateUtils;
import com.ruoyi.common.core.utils.bean.BeanUtils;
import com.ruoyi.common.security.utils.SecurityUtils;
import com.ruoyi.teaching.bo.ExamRecordBo;
import com.ruoyi.teaching.domain.Classes;
import com.ruoyi.teaching.domain.ExamDetail;
import com.ruoyi.teaching.mapper.ClassesMapper;
import com.ruoyi.teaching.mapper.ExamDetailMapper;
import com.ruoyi.teaching.mapper.StudentMapper;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.teaching.mapper.ExamRecordMapper;
import com.ruoyi.teaching.domain.ExamRecord;
import com.ruoyi.teaching.service.IExamRecordService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 学生成绩记录Service业务层处理
 *
 * @author ruoyi
 * @date 2024-04-01
 */
@Service
public class ExamRecordServiceImpl implements IExamRecordService
{
    //笔试
    public static final int WRITTEN = 1;
    //笔试
    public static final int COMPUTER = 2;

    //笔试&机试
    public static final int WRITTEN_COMPUTER = 3;
    @Autowired
    private ExamRecordMapper examRecordMapper;
    @Autowired
    private StudentMapper studentMapper;
    @Autowired
    private ExamDetailMapper examDetailMapper;
    @Autowired
    private ClassesMapper classesMapper;
    /**
     * 查询学生成绩记录
     *
     * @param id 学生成绩记录主键
     * @return 学生成绩记录
     */
    @Override
    public ExamRecordBo selectExamRecordById(Long id)
    {
 /*       ExamRecordBo result = new ExamRecordBo();
        ExamRecord examRecord = examRecordMapper.selectExamRecordById(id);
        BeanUtils.copyBeanProp(result, examRecord);

        List<ExamDetail> detailList = examDetailMapper.selectList(new LambdaQueryWrapper<ExamDetail>().eq(ExamDetail::getExamRecordId, id));
        result.setExamDetails(detailList);
        return result;*/
        return examRecordMapper.selectExamRecordBoById(id);
    }

    /**
     * 查询学生成绩记录列表
     *
     * @param examRecord 学生成绩记录
     * @return 学生成绩记录
     */
    @Override
    public List<ExamRecord> selectExamRecordList(ExamRecord examRecord)
    {
        return examRecordMapper.selectExamRecordList(examRecord);
    }

    /**
     * 新增学生成绩记录
     *
     * @param examRecord 学生成绩记录
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insertExamRecord(ExamRecord examRecord)
    {


        ExamRecordBo insertExamRecordBo = (ExamRecordBo) examRecord;

        Classes classes = classesMapper.selectClassesById(insertExamRecordBo.getClassesId());
        //表单校验
        if (classes == null) {
            throw new ServiceException("班级不存在");
        }
        List<ExamDetail> examDetails = insertExamRecordBo.getExamDetails();
        //计算平均成绩
        Integer examType = examRecord.getExamType();
        if(examType.equals(WRITTEN) || examType.equals(WRITTEN_COMPUTER))
        {
            Integer avgWrittenScore = computeWrittenAvgScore(examDetails).intValue();
            examRecord.setAvgWrittenScore(avgWrittenScore);
        }
        if(examType.equals(COMPUTER) || examType.equals(WRITTEN_COMPUTER))
        {
            Integer avgComputerScore = computeComputerAvgScore(examDetails).intValue();
            examRecord.setAvgComputerScore(avgComputerScore);
        }
        //1.新增一方
        examRecord.setCreateBy(SecurityUtils.getUsername());
        examRecord.setCreateTime(DateUtils.getNowDate());
        examRecord.setClassesName(classes.getClassName());

        examRecordMapper.insertExamRecord(examRecord);

        //2.新增多方(维护和一方关系)
        for (ExamDetail examDetail : examDetails) {
            examDetail.setExamRecordId(examRecord.getId());
            examDetailMapper.insert(examDetail);
        }

        return 1;
    }

    private Double computeComputerAvgScore(List<ExamDetail> examDetails) {
        return examDetails.stream()
                .filter(examDetail->ObjectUtils.isNotEmpty(examDetail.getComputerScore()))
                .mapToInt(ExamDetail::getWrittenScore)
                .average().orElse(0);
    }
    private Double computeWrittenAvgScore(List<ExamDetail> examDetails) {
        return examDetails.stream()
                .filter(examDetail->ObjectUtils.isNotEmpty(examDetail.getWrittenScore()))
                .mapToInt(ExamDetail::getWrittenScore)
                .average().orElse(0);
    }

    /**
     * 修改学生成绩记录
     *
     * @param examRecord 学生成绩记录
     * @return 结果
     */
    @Override
    public int updateExamRecord(ExamRecord examRecord)
    {
        examRecord.setUpdateTime(DateUtils.getNowDate());
        return examRecordMapper.updateExamRecord(examRecord);
    }

    /**
     * 批量删除学生成绩记录
     *
     * @param ids 需要删除的学生成绩记录主键
     * @return 结果
     */
    @Override
    public int deleteExamRecordByIds(Long[] ids)
    {
        return examRecordMapper.deleteExamRecordByIds(ids);
    }

    /**
     * 删除学生成绩记录信息
     *
     * @param id 学生成绩记录主键
     * @return 结果
     */
    @Override
    public int deleteExamRecordById(Long id)
    {
        return examRecordMapper.deleteExamRecordById(id);
    }

    @Override
    public List<ExamDetail> selectExamDetailList(Long classesId) {
/*        List<Student> studentList = studentMapper.selectList(new LambdaQueryWrapper<Student>().eq(Student::getClassesId, classesId));
        if (CollectionUtils.isEmpty(studentList)) {
            return Collections.emptyList();
        }
        //将学生列表转成测试详情列表
*//*        List<ExamDetail> result = new ArrayList<>(studentList.size());
        for (Student student : studentList) {
            ExamDetail detail = new ExamDetail();
            detail.setStudent(student.getName());
            result.add(detail);
        }*//*
        return studentList.stream()
                .map(student -> new ExamDetail(student.getName(),student.getId()))
                .collect(Collectors.toList());*/


        return examRecordMapper.selectExamDetailList(classesId);
    }

    @Override
    public Integer selectLastWeek(Long classesId, Integer stage) {
        ExamRecord examRecord = examRecordMapper.selectOne(
                new LambdaQueryWrapper<ExamRecord>()
                .eq(ExamRecord::getStage, stage)
                .eq(ExamRecord::getClassesId, classesId)
                .orderByDesc(ExamRecord::getWeek).last("limit 1")
        );
        if (ObjectUtils.isEmpty(examRecord)) {
            return 0;
        }
        return examRecord.getWeek();
    }
}
